package cn.hsp.login.service;

import cn.hsp.login.bean.UserDetail;
import cn.hsp.login.bean.response.LoginResp;
import cn.hsp.login.bean.response.Resp;
import cn.hsp.login.mapper.AuthMapper;
import cn.hsp.login.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author 花生皮编程(CSDN 、 简书 、 掘金 、 今日头条 、 微信公众号 、 抖音 、 快手 、 B站 、 西瓜视频)
 * 编程学习资料及开源项目见：https://juejin.cn/post/7002792005688360968
 */
@Service
public class AuthServiceImpl implements AuthService {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Resource
    private JwtUtils jwtUtils;

    @Autowired
    private AuthMapper authMapper;

    private String tokenInHeader = "Bearer ";

    @Override
    public Resp<String> register(UserDetail userDetail) {
        final String username = userDetail.getUsername();
        if (authMapper.findUserByName(username) != null) {
            return new Resp<>(Resp.ERROR, "用户已存在");
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = userDetail.getPassword();
        userDetail.setPassword(encoder.encode(rawPassword));
        authMapper.insert(userDetail);
        long roleId = userDetail.getRole().getId();
        authMapper.insertRole(userDetail.getId(), roleId);
        return new Resp<>("注册成功");
    }

    @Override
    public Resp<LoginResp> login(String username, String password) {
        Resp<LoginResp> resp = new Resp<>();
        //用户验证
        final Authentication authentication = authenticate(username, password);
        if (authentication == null) {
            resp.setCode(Resp.ERROR);
            resp.setMsg("用户名或密码错误");
        } else {
            //存储认证信息
            SecurityContextHolder.getContext().setAuthentication(authentication);
            //生成token
            final UserDetail userDetail = (UserDetail) authentication.getPrincipal();
            final String token = jwtUtils.generateAccessToken(userDetail);
            resp.setData(new LoginResp(userDetail.getId(), token));
        }
        return resp;
    }

    @Override
    public long getLogInUserId() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        final UserDetail userDetail = (UserDetail) authentication.getPrincipal();
        return userDetail.getId();
    }

    private Authentication authenticate(String username, String password) {
        try {
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException | BadCredentialsException e) {
            return null;
        }
    }
}
